<font color="green">関数の構造</font>
code:c
型名 関数名(引数) {
処理内容
return 値;
}
型名 … 関数が返す値のデータ型
関数名 … 半角英数字と _ が使用可能。先頭に数字不可、予約語は不可
引数 … 外から受け取る値。無ければ void
main関数について
プログラムは 必ず main から実行 されます。
code:c
int main(void) {
// 処理内容
return 0;
}
int main(void) … 引数を取らないことを明示
int main() … 古い書き方で、規格上は正しくない(引数チェックがされないなどのデメリットあり)
戻り値は終了ステータス
0 → 正常終了
0以外 → エラー終了
プリプロセッサ命令の一つ
指定した ヘッダファイル(.h) の内容を読み込む
指定したヘッダファイルの内容を読み込み、外部関数や定数を利用可能に
<stdio.h> を読み込むと printf や scanf が使える
? 例
3. ファイル操作の基本
FILE *fp;
// 書き込み
fp = fopen("sample.txt", "w");
fprintf(fp, "Hello, C!\n");
fclose(fp);
// 読み込み
fp = fopen("sample.txt", "r");
char buf;
fgets(buf, sizeof(buf), fp);
printf("%s", buf);
fclose(fp);
モード例
"r" 読み込み専用
"w" 書き込み専用(既存内容は消える)
"a" 追記
"rb" / "wb" バイナリ
4. バイナリファイルで構造体を保存/読み込み
typedef struct {
int id;
char name;
double score;
} Student;
int main() {
FILE *fp;
Student s1 = {1, "Taro", 89.5};
Student s2;
// 書き込み
fp = fopen("student.dat", "wb");
fwrite(&s1, sizeof(Student), 1, fp);
fclose(fp);
// 読み込み
fp = fopen("student.dat", "rb");
fread(&s2, sizeof(Student), 1, fp);
fclose(fp);
printf("ID=%d, Name=%s, Score=%.1f\n", s2.id, s2.name, s2.score);
return 0;
}
? ポイント
fwrite / fread で構造体を丸ごと保存・読み込み
バイナリモードではテキスト変換がないので正確に保存可能
5. 動的メモリ確保(malloc / free)
配列は通常サイズ固定
malloc で 実行時に必要なサイズを確保
free で解放し、メモリリークを防ぐ
int main() {
int n = 5;
int *arr = malloc(sizeof(int) * n);
for (int i = 0; i < n; i++) arri = (i+1) * 10; for (int i = 0; i < n; i++) printf("arr%d = %d\n", i, arri); free(arr);
return 0;
}
? 出力例
arr = 10
arr = 20
arr = 30
arr = 40
arr = 50
構造体と動的メモリの応用
typedef struct {
char name;
int age;
} Person;
int main() {
int n = 3;
Person *list = malloc(sizeof(Person) * n);
strcpy(list0.name, "Alice"); list0.age = 20; strcpy(list1.name, "Bob"); list1.age = 25; strcpy(list2.name, "Carol"); list2.age = 30; for (int i = 0; i < n; i++)
listi.age += 1; // 年齢を1増やす for (int i = 0; i < n; i++)
printf("%s (%d歳)\n", listi.name, listi.age); free(list);
return 0;
}
配列 × 構造体 × 動的確保 で柔軟にデータ管理可能
関数に渡す場合はポインタを使うと効率的
ポインタの注意点
NULLポインタ
int *p = NULL;
if (p != NULL) *p = 10;
ダングリングポインタ
int *p = malloc(sizeof(int));
free(p);
p = NULL; // 安全対策
初期化忘れ
int *p; // 未初期化
// *p = 10; 未定義動作
使用前に必ず初期化や NULL チェック
応用:関数とポインタ、構造体の組み合わせ
typedef struct {
char name;
int age;
} Person;
void birthday(Person *p) {
p->age += 1; // 元の構造体を直接更新
}
int main() {
Person *p = malloc(sizeof(Person));
strcpy(p->name, "Bob");
p->age = 30;
birthday(p);
printf("名前: %s, 年齢: %d\n", p->name, p->age);
free(p);
return 0;
}
ポインタ経由で関数から構造体を直接操作可能
-> は (*p).member の省略形